#ifndef DESIGN_PATTERNS_ABSTRACT_FACTORY_HPP
#define DESIGN_PATTERNS_ABSTRACT_FACTORY_HPP

namespace DesignPatterns {
	class widget;
	class motif_button;
	class motif_menu;
	class window_button;
	class window_menu;
	class factory;
	class motif_factory;
	class window_factory;
}

/// @brief Creational pattern : abstract_factory 

/// @brief The 'Abstract Product' abstract class 
class DesignPatterns::widget
{
public:
	virtual void draw() = 0;
		
};

/// @brief 'Product 1' class
class DesignPatterns::motif_button 
	: public DesignPatterns::widget
{
public:
	void draw();
};

/// @brief 'Product 2' class
class DesignPatterns::motif_menu 
	: public DesignPatterns::widget
{
public:
	void draw();
};

/// @brief 'Product 3' class
class DesignPatterns::window_button 
	: public DesignPatterns::widget
{
public:
	void draw();
};

/// @brief 'Product 4' class
class DesignPatterns::window_menu 
	: public DesignPatterns::widget
{
public:
	void draw();
};

/// @brief The 'Abstract Factory' abstract class
class DesignPatterns::factory {
public:
	virtual widget* create_button() = 0;
	virtual widget* create_menu() = 0;
};

/// @brief The 'Concrete factory 1' class
class DesignPatterns::motif_factory
	: public DesignPatterns::factory {
public:
	widget* create_button();
	widget* create_menu();
};

/// @brief The 'Concrete factory 2' class
class DesignPatterns::window_factory
	: public DesignPatterns::factory {
public:
	widget* create_button();
	widget* create_menu();
};

#endif //DESIGN_PATTERNS_ABSTRACT_FACTORY_HPP
